import { Request, Response, NextFunction } from 'express';
import ApiResponse from '@/utils/api/api-response.util';
import { isEmpty, isValidStatus } from '../common/validation.util';
import roleService from '@/services/system/role.service';
import { getLogger } from '@/utils/logger';
import { AuthRequest } from '@/types';

const logger = getLogger('role-validator', { console: false });
const consoleLogger = getLogger('role-validator');

/**
 * 验证角色创建参数
 */
export const validateRoleCreate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { roleName, roleKey, roleSort, status } = req.body;
    
    // 角色名称验证
    if (isEmpty(roleName)) {
      return ApiResponse.error(res, '角色名称不能为空', 400);
    }
    
    // 角色权限标识验证
    if (isEmpty(roleKey)) {
      return ApiResponse.error(res, '角色权限标识不能为空', 400);
    }
    
    // 角色排序验证
    if (isEmpty(roleSort) || isNaN(Number(roleSort))) {
      return ApiResponse.error(res, '角色排序必须为数字', 400);
    }
    
    // 状态验证
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    // 校验角色名称是否唯一
    const isNameUnique = await roleService.checkRoleNameUnique(roleName);
    if (!isNameUnique) {
      consoleLogger.warn('新增角色失败: 角色名称已存在', { roleName });
      return ApiResponse.error(res, '角色名称已存在', 400);
    }
    
    // 校验角色权限是否唯一
    const isKeyUnique = await roleService.checkRoleKeyUnique(roleKey);
    if (!isKeyUnique) {
      consoleLogger.warn('新增角色失败: 角色权限已存在', { roleKey });
      return ApiResponse.error(res, '角色权限已存在', 400);
    }
    
    logger.debug('角色创建参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`角色创建验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证角色更新参数
 */
export const validateRoleUpdate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { roleId, roleName, roleKey, roleSort, status } = req.body;
    
    // 角色ID验证
    if (isEmpty(roleId) || isNaN(Number(roleId))) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 角色名称验证
    if (isEmpty(roleName)) {
      return ApiResponse.error(res, '角色名称不能为空', 400);
    }
    
    // 角色权限标识验证
    if (isEmpty(roleKey)) {
      return ApiResponse.error(res, '角色权限标识不能为空', 400);
    }
    
    // 角色排序验证
    if (isEmpty(roleSort) || isNaN(Number(roleSort))) {
      return ApiResponse.error(res, '角色排序必须为数字', 400);
    }
    
    // 状态验证
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    // 校验角色是否存在
    const existRole = await roleService.selectRoleById(roleId);
    if (!existRole) {
      logger.warn('修改角色失败: 角色不存在', { roleId });
      return ApiResponse.error(res, '角色不存在', 404);
    }
    
    // 校验角色是否允许操作
    try {
      roleService.checkRoleAllowed(existRole);
    } catch (error) {
      return ApiResponse.error(res, error instanceof Error ? error.message : '不允许操作该角色', 400);
    }
    
    // 校验角色名称是否唯一
    const isNameUnique = await roleService.checkRoleNameUnique(roleName, roleId);
    if (!isNameUnique) {
      logger.warn('修改角色失败: 角色名称已存在', { roleName });
      return ApiResponse.error(res, '角色名称已存在', 400);
    }
    
    // 校验角色权限是否唯一
    const isKeyUnique = await roleService.checkRoleKeyUnique(roleKey, roleId);
    if (!isKeyUnique) {
      logger.warn('修改角色失败: 角色权限已存在', { roleKey });
      return ApiResponse.error(res, '角色权限已存在', 400);
    }
    
    logger.debug('角色更新参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`角色更新验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证删除角色参数
 */
export const validateRoleRemove = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const roleIds = req.params.roleIds.split(',').map(Number);
    
    // 角色ID验证
    if (roleIds.some(id => isNaN(id) || id <= 0)) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 检查角色是否允许删除
    for (const roleId of roleIds) {
      const role = await roleService.selectRoleById(roleId);
      if (!role) {
        continue; // 角色不存在，跳过
      }
      
      try {
        roleService.checkRoleAllowed(role);
      } catch (error) {
        return ApiResponse.error(res, error instanceof Error ? error.message : '不允许删除该角色', 400);
      }
    }
    
    logger.debug('删除角色参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`删除角色验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证角色数据权限设置参数
 */
export const validateRoleDataScope = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { roleId, dataScope, deptIds } = req.body;
    
    // 角色ID验证
    if (isEmpty(roleId) || isNaN(Number(roleId))) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 数据权限范围验证
    if (isEmpty(dataScope)) {
      return ApiResponse.error(res, '数据权限范围不能为空', 400);
    }
    
    // 自定义数据权限时，部门ID列表不能为空
    if (dataScope === '2' && (!deptIds || deptIds.length === 0)) {
      return ApiResponse.error(res, '自定义数据权限时，请选择部门', 400);
    }
    
    // 校验角色是否存在
    const existRole = await roleService.selectRoleById(roleId);
    if (!existRole) {
      logger.warn('设置数据权限失败: 角色不存在', { roleId });
      return ApiResponse.error(res, '角色不存在', 404);
    }
    
    // 校验角色是否允许操作
    try {
      roleService.checkRoleAllowed(existRole);
    } catch (error) {
      return ApiResponse.error(res, error instanceof Error ? error.message : '不允许操作该角色', 400);
    }
    
    logger.debug('角色数据权限设置参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`角色数据权限设置验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证角色授权用户参数
 */
export const validateAuthorizeUser = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const { roleId, userIds } = req.body;
    
    // 角色ID验证
    if (isEmpty(roleId) || isNaN(Number(roleId))) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 用户ID列表验证
    if (!userIds || !Array.isArray(userIds) || userIds.length === 0) {
      return ApiResponse.error(res, '用户ID列表不能为空', 400);
    }
    
    // 校验角色是否存在
    const existRole = await roleService.selectRoleById(roleId);
    if (!existRole) {
      logger.warn('角色授权用户失败: 角色不存在', { roleId });
      return ApiResponse.error(res, '角色不存在', 404);
    }
    
    // 校验角色是否允许操作
    try {
      roleService.checkRoleAllowed(existRole);
    } catch (error) {
      return ApiResponse.error(res, error instanceof Error ? error.message : '不允许操作该角色', 400);
    }
    
    logger.debug('角色授权用户参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`角色授权用户验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证取消授权用户参数
 */
export const validateCancelUserAuthorization = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const roleId = Number(req.params.roleId);
    const userId = Number(req.params.userId);
    
    // 角色ID验证
    if (isNaN(roleId) || roleId <= 0) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 用户ID验证
    if (isNaN(userId) || userId <= 0) {
      return ApiResponse.error(res, '用户ID无效', 400);
    }
    
    // 校验角色是否存在
    const existRole = await roleService.selectRoleById(roleId);
    if (!existRole) {
      logger.warn('取消授权用户失败: 角色不存在', { roleId });
      return ApiResponse.error(res, '角色不存在', 404);
    }
    
    // 校验角色是否允许操作
    try {
      roleService.checkRoleAllowed(existRole);
    } catch (error) {
      return ApiResponse.error(res, error instanceof Error ? error.message : '不允许操作该角色', 400);
    }
    
    logger.debug('取消授权用户参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`取消授权用户验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证批量取消授权用户参数
 */
export const validateCancelUserAuthorizationBatch = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { roleId, userIds } = req.body;
    
    // 角色ID验证
    if (isEmpty(roleId) || isNaN(Number(roleId))) {
      return ApiResponse.error(res, '角色ID无效', 400);
    }
    
    // 用户ID列表验证
    if (!userIds || !Array.isArray(userIds) || userIds.length === 0) {
      return ApiResponse.error(res, '用户ID列表不能为空', 400);
    }
    
    // 校验角色是否存在
    const existRole = await roleService.selectRoleById(roleId);
    if (!existRole) {
      logger.warn('批量取消授权用户失败: 角色不存在', { roleId });
      return ApiResponse.error(res, '角色不存在', 404);
    }
    
    // 校验角色是否允许操作
    try {
      roleService.checkRoleAllowed(existRole);
    } catch (error) {
      return ApiResponse.error(res, error instanceof Error ? error.message : '不允许操作该角色', 400);
    }
    
    logger.debug('批量取消授权用户参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`批量取消授权用户验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
}; 